package cn.bluech.lib.utils;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;

import java.io.DataInputStream;
import java.io.File;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StorageUtils {

    /**
     * 美化数据大小(用于显示用)
     */
    public static String beautify(long size){
        final long KB = 1024;
        final long MB = KB*1024;
        final long GB = MB*1024;
        final long TB = GB*1024;

        if(size>TB)
            return String.format(Locale.getDefault(),"%.2fTB",(float)size/TB);
        else if(size>GB)
            return String.format(Locale.getDefault(),"%.2fGB",(float)size/GB);
        else if(size>MB)
            return String.format(Locale.getDefault(),"%.2fMB",(float)size/MB);
        else if(size>KB)
            return String.format(Locale.getDefault(),"%.2fKB",(float)size/KB);
        else
            return size+"B";
    }

    public static boolean isExternalStorageMounted() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    public static String getExternalRootPath(Context context) {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File sdRoot = Environment.getExternalStorageDirectory();
            if (sdRoot == null) {
                return "";
            } else {
                return sdRoot.getAbsolutePath();
            }
        }
        return "";
    }

    public static File getExternalFileDir(Context context) {
        return getExternalFileDir(context, null);
    }

    public static File getExternalFileDir(Context context, String dirName) {
        File dir = isExternalStorageMounted() ? context
                .getExternalFilesDir(dirName) : null;
        if (dir != null) {
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
        return dir;
    }

    /**
     * 获取挂载点
     * 使用正则匹配,rootExec()可能没有换行符,未确认
     */
    public static String getSystemMountPoint() {
        String mountPoint = null;
        DataInputStream dis = null;

        try {
//            RunTimeUtil.rootExecSilent("mount > " + TMP_PATH);
            String result = RunTimeUtil.rootExec("mount");
            if(TextUtils.isEmpty(result))
                return null;

            Pattern pattern = Pattern.compile(".*\n(.*)\\s/system\\s.*");
            Matcher matcher = pattern.matcher(result);
            if(matcher.find()){
                mountPoint = matcher.group(1); // 第一个括号内的内容
                // result.indexOf(" rw") > 0 // 包含rw时为可写
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            StreamUtils.close(dis);
        }

        return mountPoint;
    }

    // 挂载 /system 分区
    public static int mountSystem(boolean writeable){
        String mountPoint = getSystemMountPoint();
        if(TextUtils.isEmpty(mountPoint))
            return -1;

        return RunTimeUtil.rootExecSilent(String.format(Locale.getDefault(),
                "mount -o remount,%s %s /system",writeable?"rw":"ro",mountPoint));
    }

    /**
     * 获取文件/文件夹(递归)大小
     */
    public static long getSize(File file) {
        if(!file.isDirectory())
            return file.length();

        long size = 0;
        for (File fileSub : file.listFiles()) {
            size += getSize(fileSub);
        }
        return size;
    }


    /**
     * 获取当前App的缓存大小
     *
     * Context.getExternalFilesDir()
     *   --> SDCard/Android/data/包名/files/ 一般放一些长时间保存的数据
     * Context.getExternalCacheDir()
     *   --> SDCard/Android/data/包名/cache/ 一般存放临时缓存数据
     */
    public static String getCacheSize(Context ctx) {
        long cacheSize = getSize(ctx.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            cacheSize += getSize(ctx.getExternalCacheDir());
        }
        return beautify(cacheSize);
    }

    /**
     * 清除当前App的缓存
     */
    public static void clearCache(Context ctx) {
        FileUtils.delete(ctx.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            FileUtils.delete(ctx.getExternalCacheDir());
            FileUtils.delete(ctx.getExternalFilesDir(null));
        }
    }
}
